<?php

namespace App\Http\Controllers\Api\V1;

use App\Models\Activity;
use App\Models\AwardSet;
use App\Models\Participant;
use App\Models\ParticipantActivity;
use App\Org\Developer\Helper;
use App\Org\Developer\JsonReturnInfo;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use DB;

/**
 * @author 陈玉琦
 * 奖品设置（1,2,3等奖，未中奖，只有四个奖项）
 */
class AwardSetController extends Controller
{
    private $fields = ['id', 'user_id', 'title', 'type'];
    /**
     * 显示奖品分类信息
     * 如果有 award_id 参数，表示中显示一条数据；否则显示 activity_id 的所有奖品分类数据。
     *
     * @return array
     */
    public function index(Request $request)
    {
        // 用户 user_id
        // if (Helper::idInvalid($user_id = $request->input('user_id', 0))) {
        //     return JsonReturnInfo::ID_ERROR;
        // }

        try {
            // 返回某个活动的所有奖品分类数据
            if (!empty($activity_id = $request->input('activity_id', 0))) {
                // 活动 activity_id
                if (Helper::idInvalid($activity_id)) {
                    return JsonReturnInfo::ID_ERROR;
                }
                // 是否是自己的资源
                $activityModel = Activity::select($this->fields)->where(['id' => $activity_id])->first();
                if (!(isset($activityModel) && $activityModel->id)) {
                    return JsonReturnInfo::infoFailure('指定活动不存在.');
                }
                // if (!Helper::isUserSelfResource($user_id, $activityModel->user_id)) {
                //     return JsonReturnInfo::NOT_SELF_RESOURCE_ERROR;
                // }
                return JsonReturnInfo::infoSuccess('返回数据成功', AwardSet::getAwardSetsByActivityId($activity_id));
            }
        } catch (\Exception $e) {
            return JsonReturnInfo::infoCatch($e);
        }
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * 添加奖品
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function store(Request $request)
    {
        /*
        // 用户 user_id
        if (Helper::idInvalid($user_id = $request->input('user_id', 0))) {
            return JsonReturnInfo::ID_ERROR;
        }

        // 活动 activity_id
        if (Helper::idInvalid($activity_id = $request->input('activity_id', 0))) {
            return JsonReturnInfo::ID_ERROR;
        }

        // 奖品内容
        if (empty($content = $request->input('content', ''))) {
            return JsonReturnInfo::infoEmpty('content');
        }

        try {*/
            // 必须是自己的资源
            /*$activityModel = Activity::select($this->fields)->where(['id' => $activity_id])->first();
            if (!(isset($activityModel) && $activityModel->id)) {
                return JsonReturnInfo::infoFailure('指定活动不存在.');
            }
            if (!Helper::isUserSelfResource($user_id, $activityModel->user_id)) {
                return JsonReturnInfo::NOT_SELF_RESOURCE_ERROR;
            }

            // content:[{level_id:2,title:'奖品名称',total:xx}, {level_id:3,title:'奖品名称',total:xx}, {level_id:4,title:'奖品名称',total:xx}]
            $contentArray = json_decode($content, true);
            if (empty($contentArray)) {//  || (count($contentArray) > 3)
                return JsonReturnInfo::infoFailure('奖品分类不能为空.');//  或者超过 3 个
            }
            $batch = [];
            foreach ($contentArray as $val) {
                if ($val['total'] <= 0) {
                    return JsonReturnInfo::infoFailure('奖品数量必须是大于 0 的正整数.');
                }
                if (Helper::idInvalid($val['level_id'])) {
                    return JsonReturnInfo::infoFailure('奖品等级 id 必须是大于 0 的正整数.');
                }
                $batch[] = [
                    'activity_id' => $activity_id,
                    'level_id' => $val['level_id'],
                    'title' => $val['title'],
                    'total' => $val['total'],
                    'surplus' => $val['total']
                ];
            }

            $result = AwardSet::insert($batch);
            if ($result) {
                return JsonReturnInfo::infoSuccess('奖品设置成功.');
            }
            return JsonReturnInfo::infoFailure('奖品设置失败.');*/

            /*
            // 奖品分类的名称            
            if (empty($award_data['title'] = $request->input('title', ''))) {
                return JsonReturnInfo::infoEmpty('title');
            }

            // 奖品分类总数量和剩余数量
            $total = intval($request->input('total', ''));
            $surplus = intval($request->input('surplus', ''));
            if ($this->_checkTotalSurplus($total, $surplus)) {
                $award_data['total'] = $total;
                $award_data['surplus'] = $surplus;
            }

            // 中奖率
            if (!empty($request->input('rate', ''))) {
                $award_data['rate'] = floatval($request->input('rate', ''));
            }
            // return $award_data;
            // 写入数据
            $awardModel = AwardSet::create($award_data);
            if (!(isset($awardModel) && $awardModel->id)) {
                return JsonReturnInfo::infoFailure('奖品分类创建失败.');
            }
            return JsonReturnInfo::infoSuccess('奖品分类创建成功.', ['award_id' => $awardModel->id]);
            */
        /*} catch (\Exception $e) {
            return JsonReturnInfo::infoCatch($e);
        }*/
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * 修改奖品分类数据
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id     awards 表中的 id
     * @return array
     */
    public function update(Request $request, $id)
    {
        // 
    }

    /**
     * 删除奖品
     *
     * @param  int  $id     awards 表中的 id
     * @return array
     */
    public function destroy(Request $request, $id)
    {
        // 
    }

    /**
     * 中奖，根据奖品分类的中奖概率进行计算
     *
     * @param Request $request
     * @return array
     */
    public function hitAward( Request $request)
    {
        // 参与者 participant_id
        // if (Helper::idInvalid($participant_id = $request->input('participant_id', 0))) {
        //     return JsonReturnInfo::ID_ERROR;
        // }

        // 参与者微信 openid
        if (empty($openid = $request->input('openid', ''))) {
            return JsonReturnInfo::infoEmpty('openid');
        }

        // 活动 activity_id
        if (Helper::idInvalid($activity_id = $request->input('activity_id', 0))) {
            return JsonReturnInfo::ID_ERROR;
        }

        // 游戏类型（打飞机、大转盘、老虎机）和成绩类型（暂时认为成绩只有分数和奖品分类id两种，那个按等级划分的成绩暂且不处理）
        // 打飞机只计算分数，大转盘和老虎机只计算奖品分类id
        // 飞机 airplane，转盘 turntable，老虎机，slot
        // if (empty($gameType = $request->input('game_type', ''))) {
        //     return JsonReturnInfo::infoEmpty('game_type');
        // }

        try {
            // 根据 openid 查询参与者的 participant_id
            $participant_id = Participant::where(['openid' => $openid])->value('id');
            if (!$participant_id) {
                return JsonReturnInfo::infoFailure('openid 错误，此参与者不存在.');
            }

            // 判断是否已经参与过抽奖
            $existAwardModel = ParticipantActivity::where([
                'participant_id' => $participant_id,
                'activity_id' => $activity_id,
            ])->where('award_set_id', '<>', 0)->first();
            if (isset($existAwardModel) && $existAwardModel->id) {
                return [
                    'code' => 2000,
                    'message' => '已参与过抽奖.',
                    'imsg' => '不能重复参与抽奖.'
                ];
            }

            // 根据参与抽奖的人数和奖品数量，计算中奖概率
            // 最好的方法是，抽奖之前有个准备按钮，点击时发送请求过来，此控制器内另外写个方法，把中奖概率的计算放在单独的方法里
            // 这里就可以直接获取了
            
            $flag = \Illuminate\Support\Facades\Cache::get('awardReady' . $activity_id);
            if (empty($flag)) {
                // 获取参与抽奖的总人数
                $counts = ParticipantActivity::where(['activity_id' => $activity_id])->count('participant_id');

                // 计算中奖概率
                $awardData = AwardSet::select(['id', 'total'])->where(['activity_id' => $activity_id])->get();
                $i = 1;
                foreach ($awardData as $val) {
                    // $rate = number_format($val['total'] / $counts, 6);
                    $rate = 0.1 * $i;
                    $result = AwardSet::where(['id' => $val['id']])->update(['rate' => $rate]);
                    if (!$result) {
                        return JsonReturnInfo::infoFailure('更新中奖概率失败.');
                    }
                    $i++;
                }
                
                \Illuminate\Support\Facades\Cache::put('awardReady' . $activity_id, 'ok', 3600 * 12);
            }

            // 开启事务
            DB::beginTransaction();

            // 查询当期活动的奖品分类和中奖概率
            // $awardData = Award::select(['id', 'activity_id', 'title', 'rate'])->where([['surplus', '<>', 0], ['activity_id', $activity_id]])->get();
            $awardData = DB::select('SELECT ass.id,ass.activity_id,ass.title,ass.level_id,al.title AS level_title,ass.surplus,ass.rate FROM thearte_award_sets ass 
LEFT JOIN thearte_award_levels al ON al.id=ass.level_id 
WHERE ass.activity_id=? AND ass.surplus<>0 AND ass.deleted_at IS NULL FOR UPDATE', [$activity_id]);

            // 只存放中奖概率的一维数组
            $rateArray = [];
            // 存放 rate 不为 0 的奖品分类数据的数组
            $awardArray = [];
            $rateSum = 0.000000;
            foreach ($awardData as $val) {
                if ($val->rate > 0.001) {
                    $rateArray[] = $val->rate;
                    $awardArray[] = $val;
                }
                $rateSum += $val->rate;
            }
            // 把未中奖的放进去
            $unAwardRate = number_format((1 - $rateSum), 6);
            $rateArray[] = $unAwardRate;
            $unAwardObj = new \stdClass();
            $unAwardObj->id = 0;
            $unAwardObj->activity_id = $activity_id;
            $unAwardObj->level_id = 1;
            $unAwardObj->title = '未中奖';
            $unAwardObj->level_title = '未中奖';
            $unAwardObj->rate = $unAwardRate;
            $awardArray[] = $unAwardObj;

            // 使用 rate 来中奖
            if (!empty($rateArray)) {
                $alias = new \App\Org\Developer\AliasMethod($rateArray);
                $index = $alias->next_rand();// $index 就是数组 $rateArray 里面的某个元素的下标

                // 参与者中奖的 award_id
                $award_set_id = $awardArray[$index]->id;
                $award_level_id = $awardArray[$index]->level_id;
                // 对于剩余量为 -1 的不进行累减，未中奖的不需要累减；
                if ($award_set_id != 0) {
                    $result1 = DB::update('UPDATE thearte_award_sets SET `surplus`=`surplus`-1 WHERE id=? AND `surplus`<>-1', [$award_set_id]);
                    if (!$result1) {
                        return JsonReturnInfo::infoFailure('更新中奖信息失败.');
                    }
                }
                $result2 = DB::update('UPDATE thearte_participant_activities SET award_set_id=?,award_time="' . \App\Org\Developer\DateHelper::dateTimeFormat() . '" WHERE participant_id=? AND activity_id=?', [$award_set_id, $participant_id, $activity_id]);
                // 我在测试时，
                // $result1 总是会成功的，
                // 但是对于同一个人，如果前后两次中奖一样，导致 $result2 是 0。
                // 需要禁止一个人反复参加抽奖
                if ($result2)
                {
                    DB::commit();
                    return JsonReturnInfo::infoSuccess('中奖数据写入成功.', [
                        'award_level_id' => $award_level_id,
                        'title' => $awardArray[$index]->title,
                        'level_title' => $awardArray[$index]->level_title
                    ]);
                } else {
                    DB::rollback();
                    return JsonReturnInfo::infoFailure('中奖数据写入失败.');
                }
            }
        } catch (\Exception $e) {
            DB::rollback();
            return JsonReturnInfo::infoCatch($e);
        }
    }

    /**
     * 所有人中奖情况
     *
     * @param Request $request
     * @return array
     */
    public function getHitAwards(Request $request)
    {
        // 活动 activity_id
        if (Helper::idInvalid($activity_id = $request->input('activity_id', 0))) {
            return JsonReturnInfo::ID_ERROR;
        }

        try {
            $sql = "SELECT p.nickname,p.headimgurl,ass.title,al.title AS level_title,pa.award_set_id FROM thearte_participant_activities AS pa 
    LEFT JOIN thearte_award_sets ass ON ass.id = pa.award_set_id 
    LEFT JOIN thearte_award_levels al ON al.id = ass.level_id 
    LEFT JOIN thearte_participants p ON p.id = pa.participant_id 
    WHERE pa.activity_id={$activity_id} AND pa.award_time IS NOT NULL AND pa.deleted_at IS NULL";

            $data = \Illuminate\Support\Facades\DB::select($sql);
            foreach($data as $k => $v) {
                $data[$k]->nickname = urldecode($v->nickname);
                // 对于没有中奖的，在 thearte_participant_activities 表中字段 award_set_id 是 0，这个需要特别处理。
                if ((1 * $v->award_set_id) == 0) {
                    $data[$k]->title = '谢谢您';
                    $data[$k]->level_title = '未中奖';
                }
            }

            $activityModel = Activity::select(['id', 'title', 'bg_image_url', 'qrcode_image_url'])->where(['id' => $activity_id])->first();

            return JsonReturnInfo::infoSuccess('获取数据成功.', [
                'data' => $data,
                'title' => $activityModel['title'],
                'qrcode_image_url' => $activityModel['qrcode_image_url'],
                'bg_image_url' => $activityModel['bg_image_url']
            ]);
        } catch (\Exception $e) {
            DB::rollback();
            return JsonReturnInfo::infoCatch($e);
        }
    }

    /**
     * 抽奖结果下载
     */
    public function download(Request $request)
    {
        try {
            // 用户 user_id
            if (Helper::idInvalid($user_id = $request->input('user_id', 0))) {
                return JsonReturnInfo::ID_ERROR;
            }

            // 活动 activity_id
            if (Helper::idInvalid($activity_id = $request->input('activity_id', 0))) {
                return JsonReturnInfo::ID_ERROR;
            }

            // 必须是用户自己的资源
            $activityModel = Activity::select($this->fields)->where(['id' => $activity_id])->first();
            if (!(isset($activityModel) && $activityModel->id)) {
                return JsonReturnInfo::infoFailure('要下载的抽奖不存在.');
            }
            if (!Helper::isUserSelfResource($user_id, $activityModel->user_id)) {
                return JsonReturnInfo::NOT_SELF_RESOURCE_ERROR;
            }

            $sql = "SELECT IF(p.username = '', p.nickname,p.username) AS username,p.mobile,ass.title,al.title AS level_title FROM thearte_participant_activities AS pa 
    LEFT JOIN thearte_award_sets ass ON ass.id = pa.award_set_id 
    LEFT JOIN thearte_award_levels al ON al.id = ass.level_id 
    LEFT JOIN thearte_participants p ON p.id = pa.participant_id 
    WHERE pa.activity_id={$activity_id} AND pa.deleted_at IS NULL";

            $data = \Illuminate\Support\Facades\DB::select($sql); // 结果中每个元素都是一个 stdClass 对象。

            foreach ($data as $k => $item) {
                $item->username = urldecode($item->username);
                $data[$k] = json_decode(json_encode($item), true);
            }

            $title = [
                'username' => '参与者姓名',
                'mobile' => '手机号码',
                'title' => '奖品名称',
                'level_title' => '奖品等级名称'
            ];
            Helper::downloadExcel($data, $title, $activityModel->title, ['username']);
        } catch (\Exception $e) {
            header("Content-type:text/html");
            return $e->getMessage();
        }
    }
}
